Passed
Branch master (b67bf6)
by Hugo
02:51
created

utils.js ➔ objectKeys   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
import PropTypes from 'prop-types';
2
import classNames from 'classnames';
3
import { Breakpoints, FloatTypes, HorizontalAlignments, VerticalAlignments, SpaceControls, ExtendedBreakpoints } from './enums';
4
5
/**
6
 * Property types for general properties.
7
 *
8
 * @returns {Object}
9
 */
10
export const GeneralPropTypes = {
11
  showFor: PropTypes.oneOf([Breakpoints.MEDIUM, Breakpoints.LARGE]),
12
  showOnlyFor: PropTypes.oneOf(objectValues(Breakpoints)),
13
  hideFor: PropTypes.oneOf([Breakpoints.MEDIUM, Breakpoints.LARGE]),
14
  hideOnlyFor: PropTypes.oneOf(objectValues(Breakpoints)),
15
  isHidden: PropTypes.bool,
16
  isInvisible: PropTypes.bool,
17
  showForLandscape: PropTypes.bool,
18
  showForPortrait: PropTypes.bool,
19
  showForSr: PropTypes.bool,
20
  showOnFocus: PropTypes.bool,
21
  isClearfix: PropTypes.bool,
22
  float: PropTypes.oneOf(objectValues(FloatTypes))
23
};
24
25
/**
26
 * Creates class names from the given arguments.
27
 *
28
 * @param {*} args
29
 * @returns {string}
30
 */
31
export function createClassName(...args) {
32
  return classNames(...args);
33
}
34
35
/**
36
 * Parses the general class names from the given properties.
37
 *
38
 * @param {Object} props
39
 * @returns {Object}
40
 */
41
export function generalClassNames(props) {
42
  return {
43
    'show-for-medium': props.showFor === Breakpoints.MEDIUM,
44
    'show-for-large': props.showFor === Breakpoints.LARGE,
45
    'show-for-small-only': props.showOnlyFor === Breakpoints.SMALL,
46
    'show-for-medium-only': props.showOnlyFor === Breakpoints.MEDIUM,
47
    'show-for-large-only': props.showOnlyFor === Breakpoints.LARGE,
48
    'hide-for-medium': props.hideFor === Breakpoints.MEDIUM,
49
    'hide-for-large': props.hideFor === Breakpoints.LARGE,
50
    'hide-for-small-only': props.hideOnlyFor === Breakpoints.SMALL,
51
    'hide-for-medium-only': props.hideOnlyFor === Breakpoints.MEDIUM,
52
    'hide-for-large-only': props.hideOnlyFor === Breakpoints.LARGE,
53
    'hide': props.isHidden,
54
    'invisible': props.isInvisible,
55
    'show-for-landscape': props.showForLandscape,
56
    'show-for-portrait': props.showForPortrait,
57
    'show-for-sr': props.showForSr,
58
    'show-on-focus': props.showOnFocus,
59
    'clearfix': props.isClearfix,
60
    'float-left': props.float === FloatTypes.LEFT,
61
    'float-center': props.float === FloatTypes.CENTER,
62
    'float-right': props.float === FloatTypes.RIGHT
63
  };
64
}
65
66
/**
67
 * Returns the keys for the given object.
68
 * This method is used for getting the keys for prop types.
69
 *
70
 * @param {Object} object
71
 * @returns {Array}
72
 */
73
export function objectKeys(object) {
74
  return Object.keys(object);
75
}
76
77
/**
78
 * Returns the values for the given object.
79
 * This method is used for getting the values for enumerables.
80
 *
81
 * @param {Object} object
82
 * @returns {Array}
83
 */
84
export function objectValues(object) {
85
  const values = [];
86
87
  for (const property in object) {
88
    if (object.hasOwnProperty(property)) {
89
      values.push(object[property]);
90
    }
91
  }
92
93
  return values;
94
}
95
96
/**
97
 * Removes properties from the given object.
98
 * This method is used for removing valid attributes from component props prior to rendering.
99
 *
100
 * @param {Object} object
101
 * @param {Array} remove
102
 * @returns {Object}
103
 */
104
export function removeProps(object, remove) {
105
  const result = {};
106
107
  for (const property in object) {
108
    if (object.hasOwnProperty(property) && remove.indexOf(property) === -1) {
109
      result[property] = object[property];
110
    }
111
  }
112
113
  return result;
114
}
115
116
/**
117
 * Returns whether or not the given value is defined.
118
 *
119
 * @param {*} value
120
 * @returns {boolean}
121
 */
122
export function isDefined(value) {
123
  return typeof value !== 'undefined';
124
}
125
126
/**
127
 * Adds a breakpoint to a class if breakpoint is specified.
128
 *
129
 * @param {String} prop
130
 * @param {String} size
131
 * @returns {string}
132
 */
133
export function addBreakpoint(prop, size) {
134
  return size === 'all' ? prop : `${size}-${prop}`;
135
}
136
137
/**
138
 * Sets direction for grid and gutters (horizontal or vertical).
139
 *
140
 * @param {boolean} isVertical
141
 * @param {String} gutters
142
 * @returns {string}
143
 */
144
export function setDirection(isVertical, gutters = null) {
145
  if (gutters) {
146
    return isVertical === true ? `grid-${gutters}-y` : `grid-${gutters}-x`;
147
  } else {
148
    return isVertical === true ? 'grid-y' : 'grid-x';
149
  }
150
}
151
152
// Flexbox Utilities
153
154
/**
155
 * Property types for flexbox utilities.
156
 *
157
 * @returns {Object}
158
 */
159
export const FlexboxPropTypes = {
160
  alignX: PropTypes.oneOf(objectValues(HorizontalAlignments)),
161
  alignY: PropTypes.oneOf(objectValues(VerticalAlignments)),
162
  selfAlignX: PropTypes.oneOf(objectValues(HorizontalAlignments)),
163
  selfAlignY: PropTypes.oneOf(objectValues(VerticalAlignments)),
164
  centerAlign: PropTypes.bool,
165
  flexContainer: PropTypes.bool,
166
  flexDirRow: PropTypes.oneOf(objectValues(ExtendedBreakpoints)),
167
  flexDirRowRev: PropTypes.oneOf(objectValues(ExtendedBreakpoints)),
168
  flexDirCol: PropTypes.oneOf(objectValues(ExtendedBreakpoints)),
169
  flexDirColRev: PropTypes.oneOf(objectValues(ExtendedBreakpoints)),
170
  flexChild: PropTypes.oneOf(objectValues(SpaceControls)),
171
  flexOrder: PropTypes.number,
172
  flexOrderSmall: PropTypes.number,
173
  flexOrderMedium: PropTypes.number,
174
  flexOrderLarge: PropTypes.number,
175
};
176
177
/**
178
 * Parses the flexbox class names from the given properties.
179
 *
180
 * @param {Object} props
181
 * @returns {Object}
182
 */
183
export function flexboxClassNames(props) {
184
  const flexClassNames = {
185
    'flex-container': props.flexContainer,
186
    'align-center-middle': props.centerAlign,
187
  };
188
189
  if (isDefined(props.alignX)) flexClassNames[`align-${props.alignX}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
190
  if (isDefined(props.alignY)) flexClassNames[`align-${props.alignY}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
191
  if (isDefined(props.flexDirRow)) flexClassNames[addBreakpoint('flex-dir-row', props.flexDirRow)] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
192
  if (isDefined(props.flexDirRowRev)) flexClassNames[addBreakpoint('flex-dir-row-reverse', props.flexDirRowRev)] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
193
  if (isDefined(props.flexDirCol)) flexClassNames[addBreakpoint('flex-dir-column', props.flexDirCol)] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
194
  if (isDefined(props.flexDirColRev)) flexClassNames[addBreakpoint('flex-dir-column-reverse', props.flexDirColRev)] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
195
  if (isDefined(props.flexChild)) flexClassNames[`flex-child-${props.flexChild}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
196
  if (isDefined(props.flexOrder)) flexClassNames[`order-${props.flexOrder}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
197
  if (isDefined(props.flexOrderSmall)) flexClassNames[`small-order-${props.flexOrder}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
198
  if (isDefined(props.flexOrderMedium)) flexClassNames[`medium-order-${props.flexOrder}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
199
  if (isDefined(props.flexOrderLarge)) flexClassNames[`large-order-${props.flexOrder}`] = true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
200
201
  return flexClassNames;
202
}
203